﻿using HslCommunication.LogNet;
using System;
using System.Collections.Generic;
using System.Device.Location;
using System.IO;
using System.Linq;
using System.Management;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace CentralVacuum.Common
{
    class Global
    {
        //1：登录隐藏配置画面
        //2：连接授权画面通道
        /// <summary>
        /// 登陆权限级别
        /// </summary>
        public static int IsLogin { get; set; }
        /// <summary>
        /// PLC采集的数据
        /// </summary>
        public static Register rData { get; set; }
        /// <summary>
        /// MQTT采集的数据
        /// </summary>
        public static Register rMQTTData { get; set; }
        /// <summary>
        /// 远程电脑的PN值。例如"BFEBFBFF00090661"
        /// </summary>
        public static string originalRemote;
        /// <summary>
        /// 系统日志文件记录
        /// </summary>
        public static ILogNet LogNet { get; set; }
        public enum Permissions
        {
            Level1 = 0,
            Level2 = 1,
            Level3 = 2,
            Level4 = 3,
            Level5 = 4,
            Level6 = 5
        }

        ///   <summary> 
        ///   获取cpu序列号     
        ///   </summary> 
        ///   <returns> string </returns> 
        public static string GetCpuInfo()
        {
            string cpuInfo = "";
            try
            {
                using (ManagementClass cimobject = new ManagementClass("Win32_Processor"))
                {
                    ManagementObjectCollection moc = cimobject.GetInstances();

                    foreach (ManagementObject mo in moc)
                    {
                        cpuInfo = mo.Properties["ProcessorId"].Value.ToString();
                        mo.Dispose();
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            return cpuInfo.ToString();
        }

        ///   <summary> 
        ///   获取硬盘ID     
        ///   </summary> 
        ///   <returns> string </returns> 
        public static string GetHDid()
        {
            string HDid = "";
            try
            {
                using (ManagementClass cimobject1 = new ManagementClass("Win32_DiskDrive"))
                {
                    ManagementObjectCollection moc1 = cimobject1.GetInstances();
                    foreach (ManagementObject mo in moc1)
                    {
                        HDid = (string)mo.Properties["Model"].Value;
                        mo.Dispose();
                    }
                }
            }
            catch (Exception)
            {

                throw;
            }
            return HDid.ToString();
        }

        ///   <summary> 
        ///   获取网卡硬件地址 
        ///   </summary> 
        ///   <returns> string </returns> 
        public static string GetMoAddress()
        {
            string MoAddress = "";
            try
            {
                using (ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration"))
                {
                    ManagementObjectCollection moc2 = mc.GetInstances();
                    foreach (ManagementObject mo in moc2)
                    {
                        if ((bool)mo["IPEnabled"] == true)
                            MoAddress = mo["MacAddress"].ToString();
                        mo.Dispose();
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
            return MoAddress.ToString();
        }

        ///  AES 加密
        /// </summary>
        /// <param name="plainText">明文</param>
        /// <param name="Key">密钥</param>
        /// <returns></returns>
        public static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
        {
            // Check arguments.
            if (plainText == null || plainText.Length <= 0)
                throw new ArgumentNullException("plainText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("IV");
            byte[] encrypted;

            // Create an Aes object
            // with the specified key and IV.
            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = Key;
                aesAlg.IV = IV;

                // Create an encryptor to perform the stream transform.
                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

                // Create the streams used for encryption.
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            //Write all data to the stream.
                            swEncrypt.Write(plainText);
                        }
                        encrypted = msEncrypt.ToArray();
                    }
                }
            }

            // Return the encrypted bytes from the memory stream.
            return encrypted;
        }

        /// <summary>
        ///  AES 解密
        /// </summary>
        /// <param name="cipherText">密文</param>
        /// <param name="Key">密钥</param>
        /// <returns></returns>
        public static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV)
        {
            // Check arguments.
            if (cipherText == null || cipherText.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("IV");
            
            // Declare the string used to hold
            // the decrypted text.
            string plaintext = null;

            // Create an Aes object
            // with the specified key and IV.
            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = Key;
                aesAlg.IV = IV;

                // Create a decryptor to perform the stream transform.
                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

                // Create the streams used for decryption.
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {

                            // Read the decrypted bytes from the decrypting stream
                            // and place them in a string.
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }
            }

            return plaintext;
        }

        public static void getCurrentPosition(out double latitude, out double longitude)//通过GPS模块获得地址
        {
            latitude = 0;
            longitude = 0;
            GeoCoordinateWatcher watcher = new GeoCoordinateWatcher();
            //watcher.Start(); //started watcher
            watcher.TryStart(false, TimeSpan.FromMilliseconds(1000));
            GeoCoordinate coord = watcher.Position.Location;
            if (coord.IsUnknown != true)
            {
                latitude = coord.Latitude; //latitude经度
                longitude = coord.Longitude;  //logitude维度
            }
        }
    }

    /// <summary>
    /// 上升沿
    /// </summary>
    public class R_TRIG
    {
        public bool Last { get; private set; } // 这个属性存储上一次的bool状态,get;private set;这个写法相当于PLC的 Output接口
                                               // 这个属性填被检测的bool量,set;相当于PLC的Input接口
        public bool CLK
        {
            set
            {
                Q = value && !Last;//我们知道上升沿是从0变1的一瞬间，所以本次扫描为真上次为假时就产生了上升沿
                Last = value;//每个扫描周期刷新参考位
            }
        }
        // 这个就是检测的状态，外部获取这个变量就知道上升沿有没有产生
        // 相当于PLC的 Output接口
        public bool Q { get; private set; }
    }

    /// <summary>
    /// 下升沿
    /// </summary>
    public class F_TRIG
    {
        public bool Last { get; private set; }
        public bool CLK
        {
            set
            {
                Q = !value && Last;//1变0 上次为真本次为假
                Last = value;
            }
        }
        public bool Q { get; private set; }
    }
}
